﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;

namespace Chart
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        Random rd = new Random();
        private const int onedayMinute = 60 * 24;
        /// <summary>
        /// 24小时5分钟数量[60/5 * 24]
        /// </summary>
        private const int oneday5Minute = 12 * 24;

        public DateTime sdt;
        public DateTime edt;
        
        public MainWindow()
        {
            sdt = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 08:00"));
            edt = sdt.AddDays(1);
            //这里初始化各种变量
            CreateLineTestData();
            //加载完默认的控件
            InitializeComponent();

            //加载Chart
            DrawAllChart();

            //加载鼠标线 放到下面的loaded事件中
            //Initmoveleft();

        }

        /// <summary>
        /// 折线图的数据字典
        /// </summary>
        public Dictionary<DateTime, double> dicLineChartData = new Dictionary<DateTime, double>();
        /// <summary>
        /// 创建的随机测试数据
        /// </summary>
        private void CreateLineTestData()
        {
            DateTime _sdt = sdt;
            Dictionary<DateTime, double> dicData = new Dictionary<DateTime, double>();
            for (int i = 0; i < oneday5Minute + 1; i++)
            {
                dicData.Add(_sdt, rd.Next(3, 14));
                _sdt = _sdt.AddMinutes(5);
            }
            dicLineChartData = dicData;
        }

        private void DrawLineChart()
        {
            var model = new PlotModel
            {
                Padding = new OxyThickness(0, 0, 20, 0),
                PlotAreaBorderColor = OxyColors.LightGray
            };
            LinearAxis leftAxis = new LinearAxis()
            {
                Position = AxisPosition.Left,
                TickStyle = TickStyle.Outside,
                TicklineColor = OxyColors.LightGray,
                MinimumMinorStep = 1,
                LabelFormatter = _ => _ + "",
                Maximum = 24
            };
            var dateTimeAxis1 = new DateTimeAxis
            {
                TickStyle = TickStyle.Inside,
                Position = AxisPosition.Bottom,
                TicklineColor = OxyColors.LightGray,
                Minimum = DateTimeAxis.ToDouble(sdt),
                Maximum = DateTimeAxis.ToDouble(edt),
            };
            model.Axes.Add(leftAxis);
            model.Axes.Add(dateTimeAxis1);
            var series = new LineSeries
            {
                Color = OxyColor.FromRgb(0, 131, 255),
                StrokeThickness = 1.5,
                Smooth = false
            };
            foreach (var chartitem in dicLineChartData)
            {
                series.Points.Add(DateTimeAxis.CreateDataPoint(chartitem.Key, chartitem.Value));
            }
            model.Series.Add(series);

            var controller = new PlotController();
            controller.UnbindAll();
            line_chart.Controller = controller;

            line_chart.DataContext = model;
        }
        public void DrawAllChart()
        {
            //加载折线图
            DrawLineChart();
            //加载柱状图
            DrawColChart();
        }


        private void DrawColChart()
        {
            //初始化柱状图数据,顺序下来，要检查Array的Lenth
            List<DataItem> ditems = InitDataList(col_datavals);
            var model = new PlotModel
            {
                Padding = new OxyThickness(23, 20, 3, 0),
                PlotAreaBorderColor = OxyColors.LightGray
            };
            var categoryAxis = new CategoryAxis
            {
                Position = AxisPosition.Top,
                GapWidth = 0,///0.1 柱状图占满
                LabelField = "Label",
                ItemsSource = ditems,
                TicklineColor = OxyColor.FromRgb(249, 255, 251),
                TickStyle = TickStyle.Inside,
                IsTickCentered = false
            };
            //EndPosition = 0 坐标反过来 
            LinearAxis rightAxis = new LinearAxis()
            {
                Position = AxisPosition.Right,
                TickStyle = TickStyle.Outside,
                TicklineColor = OxyColors.LightGray,
                MinimumMinorStep = 1,
                LabelFormatter = _ => _ + "",
                Minimum = 0,
                EndPosition = 0,
                StartPosition = 1
            };
            model.Axes.Add(categoryAxis);
            model.Axes.Add(rightAxis);
            var colseries = new ColumnSeries
            {
                FillColor = OxyColor.FromRgb(91, 178, 187),
                ItemsSource = ditems,
                ValueField = "Value"
            };
            model.Series.Add(colseries);
            var controller = new PlotController();
            controller.UnbindAll();
            col_chart.Controller = controller;
            col_chart.DataContext = model;
        }

        //第一次加载和sizechanged中都要调用
        //修改高度，和刷新界面的参数
        private void Initmoveleft()
        {
            double a = line_chart.ActualModel.PlotArea.Height;
            double b = col_chart.ActualModel.PlotArea.Height;
            moveleftlenth = a + b;

            linePoint.Width = line_chart.ActualModel.PlotArea.Width;
            linePoint.Left = line_chart.ActualModel.PlotArea.Left;
            linePoint.Right = line_chart.ActualModel.PlotArea.Right;
            linePoint.Bottom = line_chart.ActualModel.PlotArea.Bottom;
            linePoint.Top = col_chart.ActualModel.PlotArea.Top;

            moveleft.Height = moveleftlenth;
            moveleft.Margin = new Thickness(linePoint.Left, linePoint.Top, 0, 0);
        }

        /// <summary>
        /// System.Windows.Point [public] [struct]
        /// </summary>
        Point point = new Point(0, 0);
 
        public double[] col_datavals = new double[] { 7, 3, 4, 0, 9, 0, 0, 5, 7, 9, 2, 3, 5, 2, 6, 9, 3, 2, 5, 7, 9, 3 };
        public double[] line_datavals;

        public static readonly string[] arrLabel = new string[] {
                "8:00", "9:00", "10:00", "11:00", "12:00","13:00",
                "14:00", "15:00", "16:00", "17:00","18:00", "19:00",
                "20:00", "21:00","22:00", "23:00","00:00", "1:00",
                "2:00", "3:00","4:00", "5:00","6:00", "7:00" };

        public double zeroValHeight = 0.8;

        private List<DataItem> InitDataList(double[] vals)
        {
            var ditems = new List<DataItem>();
            for (int i = 0; i < arrLabel.Length; i++)
            {
                double t_val;
                if (i > vals.Length-1)
                {
                    t_val = 0;
                }
                else
                {
                    t_val = (double)vals[i];
                    if (t_val ==0)
                    {
                        t_val = zeroValHeight;
                    }
                }
                ditems.Add(new DataItem() { Label = arrLabel[i],Value = t_val });
            }
            return ditems;

        }

        private double moveleftlenth;
        private bool hasloadedchart;
        private LinePoint linePoint = new LinePoint();


        private void MoveArea_Loaded(object sender, RoutedEventArgs e)
        {
            //while (true)
            //{
            //    if (col_chart?.ActualModel?.PlotArea.Height != 0
            //        && line_chart?.ActualModel?.PlotArea.Height != 0)
            //    {
            //        double a1 = line_chart.ActualModel.PlotArea.Height;
            //        double b1 = col_chart.ActualModel.PlotArea.Height;
            //        moveleftlenth = a1 + b1;
            //        break;
            //    }
            //}
            moveleft.Width = 0.5;
            moveleft.Background = Brushes.Red;

            hasloadedchart = true;
            Initmoveleft(); // MoveArea界面第一次加载
        }

        private void MoveArea_MouseEnter(object sender, MouseEventArgs e)
        {
            if (moveleft.Visibility == Visibility.Hidden)
            {
                moveleft.Visibility = Visibility.Visible;
                tip_border.Visibility = Visibility.Visible;
            }
        }

        private void MoveArea_MouseLeave(object sender, MouseEventArgs e)
        {
            if (moveleft.Visibility == Visibility.Visible)
            {
                moveleft.Visibility = Visibility.Hidden;
                tip_border.Visibility = Visibility.Hidden;
            }
        }

        private int cPoint = 0;
        private DateTime tempDt;
        private void MoveArea_MouseMove(object sender, MouseEventArgs e)
        {
            point = e.GetPosition(grid_chart);
            //Console.WriteLine();
            double a = line_chart.ActualModel.PlotArea.Height;
            double b = col_chart.ActualModel.PlotArea.Height;
            //每次移动都触发,做出if判断
            if ( a+b != moveleftlenth)
            {
                Initmoveleft();
            }

            moveleft.Margin = new Thickness(point.X, linePoint.Top, 0, 0);
            //Mouse Move Tip
            if (point.X < linePoint.Width / 2)
            {
                //显示在右边
                tip_border.Margin = new Thickness(point.X + 20, point.Y + 60, 0, 0);
            }
            else
            {
                //显示在左边
                tip_border.Margin = new Thickness(point.X - 150, point.Y + 60, 0, 0);
            }
            //范围是 0-288 一共289个点
            cPoint = (int)((point.X- linePoint.Left) * oneday5Minute / linePoint.Width + 0.6);
            if (cPoint>=0 && cPoint <= 288)
            {
                //横坐标在图表的有效范围内
                tempDt = sdt.AddMinutes(cPoint * 5);
                //获取水位5分钟
                double water5val = dicLineChartData[tempDt];
                string t_val;
                int thour = (tempDt - sdt).Hours;//用来计算时间的间隔 鼠标所在时间减去早上8点
                //从数组获取时雨量的
                if (thour < col_datavals.Length)
                {
                    t_val = col_datavals[thour] +"mm";
                }
                else
                {
                    t_val = "NULL";
                }
                //最终显示
                tip_text.Text = $"{tempDt}\n水位5分钟: {water5val}mm\n时雨量: {t_val}";
                //:\n数组{thour}:{t_val}"
                Console.WriteLine();

                moveleft.Visibility = Visibility.Visible;
                tip_border.Visibility = Visibility.Visible;
            }
            else
            {
                //隐藏线框或者不改变内容
                moveleft.Visibility = Visibility.Hidden;
                tip_border.Visibility = Visibility.Hidden;
            }
        }

        private void MoveArea_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (!hasloadedchart)
            {
                return;
            }
            //MoveArea_SizeChanged
            Initmoveleft();
        }

    }


    public struct LinePoint
    {
        public double Left { get; set; }
        public double Right { get; set; }
        public double Top { get; set; }
        public double Bottom { get; set; }
        public double Width { get; set; }
    }

    public class DataItem
    {
        public string Label { get; set; } = "";
        public double Value { get; set; } = 0;
    }


}
